<template>
  <div style="width: 100%; height: 100%; display: flex; align-items: center">
    <!-- <div style="position: absolute; left: 0px; top: 0px; color: red">
      {{ formattedTime }}
    </div> -->
    <div
      v-if="fullScreen"
      @click="fullScreen = false"
      id="fullContent"
      style="
        z-index: 1000;
        position: absolute;
        width: 100%;
        height: 100%;
        background: red;
        top: 0;
        left: 0;
        margin: 0;
        padding: 0;
        over-flow: hidden;
        scrollbar-width: none;
        -ms-overflow-style: none;
      "
    >
      <el-carousel
        trigger="click"
        v-if="isPlay && curProgramType == '图片' && playMode == 0"
        :interval="2000"
        height="100vh"
        style="width: 100%"
      >
        <el-carousel-item
          v-for="(item, index) in programList[curMainProgram].programs"
          :key="index"
        >
          <img
            style="width: 100%; height: 100%"
            :src="resourceRoot + item.media"
            alt=""
          />
        </el-carousel-item>
      </el-carousel>
      <img
        @click="fullScreenPhoto"
        style="height: 100%; width: 100%"
        v-if="isPlay && curProgramType == '图片' && playMode == 1"
        :src="
          resourceRoot +
          programList[curMainProgram].programs[curSonProgram].media
        "
        alt=""
      />
    </div>
    <div
      style="
        flex: 2;
        height: 99%;

        display: flex;
        flex-direction: column;
        align-items: center;
      "
    >
      <div
        style="
          display: flex;
          align-items: center;
          justify-content: space-between;
          color: #cacaca;
          width: 100%;
        "
      >
        <div style="font-size: 1vw; color: white">节目列表</div>
        <div style="display: flex; align-items: center; font-size: 0.5vw">
          <div
            @click="getProgramList"
            style="
              display: flex;
              align-items: center;
              margin-right: 15px;
              cursor: pointer;
            "
          >
            <img
              src="../assets/刷新.png"
              style="width: 15px; height: 15px; margin-right: 5px"
              alt=""
            />
            刷新
          </div>
          <div
            @click="gotoAddProgramPage"
            style="
              display: flex;
              align-items: center;
              margin-right: 15px;
              cursor: pointer;
            "
          >
            <img
              src="../assets/添加.png"
              style="width: 15px; height: 15px; margin-right: 5px"
              alt=""
            />
            添加
          </div>
          <div
            @click="deleteAll"
            style="display: flex; align-items: center; cursor: pointer"
          >
            <img
              src="../assets/全部删除.png"
              style="width: 15px; height: 15px; margin-right: 5px"
              alt=""
            />
            全部删除
          </div>
        </div>
      </div>
      <div
        style="
          width: 95%;
          flex: 1;
          background: #1c1c1c;
          margin-top: 10px;
          border-radius: 10px;
          border: solid 2px #393939;
          display: flex;
          flex-direction: column;
          align-items: center;
          overflow-y: auto;
          -ms-overflow-style: none;
          scrollbar-width: none;
        "
      >
        <div
          v-for="(item, index) in programList"
          :key="index"
          style="
            width: 80%;
            display: flex;
            flex-direction: column;
            margin-top: 20px;
          "
        >
          <div
            @click="selectMainProgram(index)"
            style="
              cursor: pointer;
              width: 100%;
              padding: 10px 0;

              display: flex;
              align-items: center;
              border-radius: 5px;
            "
            :style="{
              background: selectedMainProgram == index ? '#27C48F' : '#282828',
              color: selectedMainProgram == index ? '#F9FDFC' : '#DCDCDC',
            }"
          >
            <img
              :src="
                selectedMainProgram == index
                  ? require('../assets/收起.png')
                  : require('../assets/展开.png')
              "
              style="width: 15px; height: 15px; margin: 0 10px"
              alt=""
            />
            <div style="flex: 1; text-align: left">
              {{ item.program_name }}
            </div>
            <div style="font-size: 13px">{{ item.pgDuration }}</div>
            <img
              :src="
                selectedMainProgram == index
                  ? require('../assets/deleteLighter.png')
                  : require('../assets/delete.png')
              "
              style="width: 15px; height: 15px; margin: 0 10px"
              alt=""
            />
          </div>
          <div
            v-if="selectedMainProgram == index"
            style="width: 100%; display: flex; flex-direction: column"
          >
            <div
              v-for="(sonItem, sonIndex) in item.programs"
              :key="sonIndex"
              style="width: 100%; display: flex; justify-content: end"
            >
              <div
                @click="selectSonProgram(sonIndex, sonItem)"
                style="
                  cursor: pointer;
                  width: 200px;
                  overflow: hidden;
                  padding: 10px 0;
                  margin-top: 10px;
                  border-radius: 5px;
                  text-align: left;
                  padding-left: 10px;
                  text-overflow: ellipsis;
                "
                :style="{
                  background:
                    selectedSonProgram == sonIndex ? '#27C48F' : '#282828',
                  color: selectedSonProgram == sonIndex ? '#F9FDFC' : '#cccccc',
                }"
              >
                {{ sonItem.media }}
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <div
      style="
        flex: 9;
        height: 99%;

        display: flex;
        flex-direction: column;
        align-items: center;
      "
    >
      <div
        style="
          display: flex;
          align-items: center;
          justify-content: space-between;
          color: #cacaca;
          width: 98%;
        "
      >
        <div style="font-size: 20px; color: white">播放界面</div>
      </div>
      <div
        id="contentBox"
        style="
          width: 98%;
          flex: 1;
          background: #1c1c1c;
          margin-top: 10px;
          border-radius: 10px;
          border: solid 2px #393939;
          display: flex;
          flex-direction: column;
          align-items: center;
          color: #a1a1a1;
          overflow: hidden;
        "
      >
        <div
          id="realContent"
          style="width: 100%; height: 85%; background: black; over-flow: hidden"
        >
          <div
            v-if="curProgramType == '视频'"
            style="
              width: 100%;
              height: 100%;
              background: black;
              display: flex;
              justify-content: center;
              align-items: center;
            "
          >
            <video
              id="play_box"
              webkit-playsinline="true"
              x-webkit-airplay="true"
              playsinline="true"
              x5-video-player-type="h5"
              x5-video-player-fullscreen="false"
              x5-video-orientation="portrait"
              preload="none"
              autoplay
              controls
              style="object-fit: contain; width: 100%"
              :style="{
                height: contentHeight + 'px',
              }"
              src=""
            ></video>
          </div>
          <div
            id="textBox"
            v-if="curProgramType == '文本'"
            style="
              height: 100%;
              background: black;
              object-fit: 100% 100%;
              display: flex;
              align-items: center;
              flex-direction: column;
              justify-content: space-between;
              overflow: hidden;
            "
            :style="{
              width: windowWidth + 'px',
            }"
          >
            <div
              style="width: 100%"
              v-for="(item, index) in rowNum"
              :key="index"
            >
              <div
                v-if="again && isPlay"
                class="marquee-row"
                :style="{
                  fontSize: curFontSize + 'px',
                  lineHeight: curFontSize + 'px',
                  height: curFontSize + 'px',
                  color: curFontColor,
                }"
              >
                <div
                  class="marquee-content"
                  :ref="'animElement' + index"
                  :style="{
                    '--char-width': charWidth + 'px',
                   
                  }"
                >
                  {{ textContent }}
                </div>
              </div>
            </div>
          </div>
          <div
            id="pptCanvas"
            v-if="curProgramType == 'ppt'"
            style="
              width: 100%;
              height: 100%;
              background: black;
              object-fit: 100% 100%;
              display: flex;
              align-items: center;
            "
          >
            <!-- <div
              v-if="isPlay && curProgramType == 'ppt' && playMode == 1"
              id="placeholder"
              style="width: 100%; height: 100%"
            ></div> -->
            <PPTViewComponent
              :url="pptUrl"
              :pptKey="pptKey"
              :hostname="hostname"
              style="width: 100%; height: 100%"
              v-if="isPlay && curProgramType == 'ppt' && playMode == 1"
            >
            </PPTViewComponent>
          </div>
          <div
            id="notVideo"
            v-if="curProgramType == '图片' || curProgramType == '网页'"
            style="
              width: 100%;
              height: 100%;
              background: black;
              object-fit: 100% 100%;
              display: flex;
              align-items: center;
            "
          >
            <el-carousel
              v-if="isPlay && curProgramType == '图片' && playMode == 0"
              trigger="click"
              :interval="2000"
              :type="photoType"
              height="60vh"
              style="width: 100%"
            >
              <el-carousel-item
                v-for="(item, index) in programList[curMainProgram].programs"
                :key="index"
              >
                <img
                  style="width: 100%; height: 100%"
                  @click="fullScreenPhoto"
                  :src="resourceRoot + item.media"
                  alt=""
                />
              </el-carousel-item>
            </el-carousel>
            <img
              @click="fullScreenPhoto"
              style="width: 100%; height: 100%"
              v-if="isPlay && curProgramType == '图片' && playMode == 1"
              :src="
                resourceRoot +
                programList[curMainProgram].programs[curSonProgram].media
              "
              alt=""
            />

            <iframe
              v-if="isPlay && curProgramType == '网页'"
              :src="curWebUrl"
              style="width: 100%; height: 100%"
            ></iframe>
          </div>
        </div>

        <div style="width: 99%; height: 15%; margin: 20px 0; display: flex">
          <div
            style="
              display: flex;
              flex-direction: column;
              flex: 3;
              margin-right: 10px;
            "
          >
            <div style="width: 100%; text-align: left">预览操作：</div>
            <div
              style="
                flex: 1;
                width: 100%;
                height: 300px;
                background: yellow;
                background: #282828;
                margin-top: 10px;
                border-radius: 10px;
                display: flex;
                align-items: center;
                justify-content: space-around;
              "
            >
              <button
                @click="playLastOne"
                v-if="
                  curProgramType == '文本' ||
                  (curProgramType == '图片' && playMode == 1) ||
                  (curProgramType == 'ppt' && playMode == 1) ||
                  curProgramType == '视频' ||
                  curProgramType == '网页'
                "
                style="
                  background: #27c48f;
                  color: white;
                  width: 100px;
                  padding: 10px 0;
                "
              >
                上一个
              </button>
              <button
                @click="onPlayer"
                style="
                  background: #27c48f;
                  color: white;
                  width: 100px;
                  padding: 10px 0;
                "
              >
                播放
              </button>
              <button
                v-if="!isPause"
                @click="onPause"
                style="
                  background: #27c48f;
                  color: white;
                  width: 100px;
                  padding: 10px 0;
                "
              >
                暂停
              </button>
              <button
                v-if="isPause"
                @click="onContinute"
                style="
                  background: #27c48f;
                  color: white;
                  width: 100px;
                  padding: 10px 0;
                "
              >
                继续
              </button>
              <button
                @click="onStop"
                style="
                  background: #27c48f;
                  color: white;
                  width: 100px;
                  padding: 10px 0;
                "
              >
                停止
              </button>
              <button
                @click="onPlayer"
                style="
                  background: #27c48f;
                  color: white;
                  width: 100px;
                  padding: 10px 0;
                "
              >
                重播
              </button>
              <button
                @click="playNextOne"
                v-if="
                  curProgramType == '文本' ||
                  (curProgramType == '图片' && playMode == 1) ||
                  (curProgramType == 'ppt' && playMode == 1) ||
                  curProgramType == '视频' ||
                  curProgramType == '网页'
                "
                style="
                  background: #27c48f;
                  color: white;
                  width: 100px;
                  padding: 10px 0;
                "
              >
                下一个
              </button>
              <button
                v-if="
                  (curProgramType == 'ppt' && playMode == 1) ||
                  curProgramType == '视频' ||
                  curProgramType == '网页'
                "
                style="
                  background: #27c48f;
                  color: white;
                  width: 100px;
                  padding: 10px 0;
                "
              >
                静音
              </button>
              <button
                @click="fullscreenDiv"
                style="
                  background: #27c48f;
                  color: white;
                  width: 100px;
                  padding: 10px 0;
                "
              >
                全屏
              </button>
            </div>
          </div>
          <div style="display: flex; flex-direction: column; flex: 2">
            <div style="width: 100%; text-align: left">当前节目信息：</div>
            <div
              style="
                flex: 1;
                width: 100%;
                height: 300px;

                background: #282828;
                margin-top: 10px;
                border-radius: 10px;
                display: flex;
                flex-direction: column;
                justify-content: center;
                align-items: center;
                font-size: 12px;
              "
            >
              <div
                style="
                  width: 80%;
                  height: 20px;

                  display: flex;
                  align-items: center;
                "
              >
                <div
                  style="
                    flex: 1;
                    height: 20px;
                    display: flex;
                    align-items: center;
                  "
                >
                  <div style="flex: 1; text-align: right; margin-right: 10px">
                    节目单:
                  </div>
                  <div style="flex: 1; text-align: left">
                    {{
                      programInfo.programName == null
                        ? "/"
                        : programInfo.programName
                    }}
                  </div>
                </div>
                <div
                  style="
                    flex: 1;
                    height: 20px;
                    display: flex;
                    align-items: center;
                  "
                >
                  <div style="flex: 1; text-align: right; margin-right: 10px">
                    计划类型:
                  </div>
                  <div style="flex: 1; text-align: left">
                    {{
                      programInfo.programType == null
                        ? "/"
                        : programInfo.programType
                    }}
                  </div>
                </div>
              </div>
              <div
                style="
                  width: 80%;
                  height: 20px;

                  display: flex;
                  align-items: center;
                "
              >
                <div
                  style="
                    flex: 1;
                    height: 20px;
                    display: flex;
                    align-items: center;
                  "
                >
                  <div style="flex: 1; text-align: right; margin-right: 10px">
                    资源总量:
                  </div>
                  <div style="flex: 1; text-align: left">
                    {{
                      programInfo.resourceNum == null
                        ? "/"
                        : programInfo.resourceNum
                    }}
                  </div>
                </div>
                <div
                  style="
                    flex: 1;
                    height: 20px;
                    display: flex;
                    align-items: center;
                  "
                >
                  <div style="flex: 1; text-align: right; margin-right: 10px">
                    计划日期:
                  </div>
                  <div style="flex: 1; text-align: left">
                    {{
                      programInfo.programDate == null
                        ? "/"
                        : programInfo.programDate
                    }}
                  </div>
                </div>
              </div>
              <div
                style="
                  width: 80%;
                  height: 20px;

                  display: flex;
                  align-items: center;
                "
              >
                <div
                  style="
                    flex: 1;
                    height: 20px;
                    display: flex;
                    align-items: center;
                  "
                >
                  <div style="flex: 1; text-align: right; margin-right: 10px">
                    节目时长:
                  </div>
                  <div style="flex: 1; text-align: left">
                    {{
                      programInfo.duration == null ? "/" : programInfo.duration
                    }}
                  </div>
                </div>
                <div
                  style="
                    flex: 1;
                    height: 20px;
                    display: flex;
                    align-items: center;
                  "
                >
                  <div style="flex: 1; text-align: right; margin-right: 10px">
                    启动时间:
                  </div>
                  <div style="flex: 1; text-align: left">
                    {{
                      programInfo.playTime == null ? "/" : programInfo.playTime
                    }}
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <!-- <div style="display: flex; align-items: center">
      <button @click="startPPT">开始</button>
      <button @click="pausePPT">暂停</button>
      <button @click="lastPPT">上一页</button>
      <button @click="nextPPT">下一页</button>
    </div> -->
  </div>
</template>

<script>
import request from "../axios/request";
import flvjs from "flv.js";
import PPTViewComponent from "../components/PPTViwer.vue";

export default {
  components: { PPTViewComponent },
  data() {
    return {
      photoType: "card",
      videoUrl: null,
      tokenId: null,
      isPlay: false,
      programList: [],
      selectedMainProgram: null,
      curMainProgram: null,
      selectedSonProgram: null,
      curSonProgram: null,
      easyplayer: null,
      curSuffix: null,
      curPid: null,
      curFid: null,
      curProgramType: null,
      selectedProgramType: null,
      playMode: null,
      socket: null,
      curPlayMode: null,
      flvPlayer: null,
      speedAdjustInterval: null,
      endedController: null,
      fullScreen: false,
      resourceRoot: null,
      retryTimeout: 10000,
      docEditor: null,
      timer: null,
      seconds: 0,
      isRunning: false,
      hostname: null,
      curWebUrl: null,
      timerWeb: null,
      programInfo: {
        programName: null,
        programType: null,
        resourceNum: null,
        programDate: null,
        duration: null,
        playTime: null,
      },
      contentHeight: null,
      isPause: false,
      rowNum: 0,
      curFontSize: null,
      duration1: null,
      duration2: null,
      textContent: null,
      charWidth: null,
      windowWidth: null,
      rowArr: null,
      again: false,
      pptUrl: null,
      pptKey: null,
      curSonIndex: 0,
      curFontColor: null,
    };
  },
  computed: {
    formattedTime() {
      const hours = Math.floor(this.seconds / 3600);
      const minutes = Math.floor((this.seconds % 3600) / 60);
      const secs = this.seconds % 60;
      return `${String(hours).padStart(2, "0")}:${String(minutes).padStart(
        2,
        "0"
      )}:${String(secs).padStart(2, "0")}`;
    },
  },
  methods: {
    playNextOne() {
      console.log("播放下一个");
      if (!this.isPlay) {
        return;
      }
      if (this.curProgramType == "视频") {
        this.onStop();
        this.isPlay = true;
        if (this.playMode == 0) {
          //节目
          this.playVideoProgram(this.curSonIndex + 1, false);
        } else {
          //素材
          this.playVideoProgram(this.curSonIndex + 1, true);
        }
      }
    },
    playLastOne() {
      console.log("播放上一个");
      if (!this.isPlay) {
        return;
      }
      if (this.curProgramType == "视频") {
        this.onStop();
        this.isPlay = true;
        let aimIndex = this.curSonIndex - 1;
        if (aimIndex < 0) {
          aimIndex = this.programList[this.curMainProgram].programs.length - 1;
        }
        if (this.playMode == 0) {
          //节目
          this.playVideoProgram(aimIndex, false);
        } else {
          //素材
          this.playVideoProgram(aimIndex, true);
        }
      }
    },
    async onContinute() {
      let videoElment = document.getElementById("play_box");
      videoElment.play();
      this.isPause = false;
    },
    async deleteAll() {
      let res = await request({
        url: "/program/api/deleteAllProgram",
        method: "DELETE",
      });
      if (res.data.status == 200) {
        this.getProgramList();
      }
    },
    gotoAddProgramPage() {
      this.$router.push("/AddProgramView");
    },
    refreshProgramList() {
      this.getProgramList();
    },
    goNext() {
      this.docEditor.serviceCommand("GoToNextSlideInSlideShow", null);
    },
    startPPT() {
      this.docEditor.serviceCommand("StartSlideShow", null);
    },
    pausePPT() {
      this.docEditor.serviceCommand("PauseSlideShow", null);
    },
    lastPPT() {
      this.docEditor.serviceCommand("GoToPreviousSlideInSlideShow", null);
    },
    nextPPT() {
      this.docEditor.serviceCommand("GoToNextSlideInSlideShow", null);
    },
    fullscreenDiv() {
      let element = null;
      if (this.curProgramType == "ppt") {
        element = document.getElementsByName("frameEditor")[0];
      } else if (this.curProgramType == "视频") {
        element = document.getElementById("play_box");
      } else if (this.curProgramType == "图片") {
        this.fullScreenPhoto();
        return;
      } else if (this.curProgramType == "网页") {
        element = document.getElementById("notVideo");
      } else if (this.curProgramType == "文本") {
        element = document.getElementById("realContent");
      }

      console.log(element);
      if (element.requestFullscreen) {
        element.requestFullscreen().catch((err) => {
          console.error("全屏失败:", err);
        });
      } else if (element.mozRequestFullScreen) {
        // Firefox
        element.mozRequestFullScreen();
      } else if (element.webkitRequestFullscreen) {
        // Chrome/Safari
        element.webkitRequestFullscreen();
      } else if (element.msRequestFullscreen) {
        // IE/Edge
        element.msRequestFullscreen();
      }
    },
    fullScreenPhoto() {
      this.toggleFullScreen();
      this.fullScreen = true;
    },
    toggleFullScreen() {
      const element = document.documentElement;
      const isFullScreen =
        document.fullscreenElement ||
        document.webkitFullscreenElement ||
        document.mozFullScreenElement;

      if (!isFullScreen) {
        if (element.requestFullscreen) {
          element.requestFullscreen();
        } else if (element.webkitRequestFullscreen) {
          element.webkitRequestFullscreen();
        } else if (element.mozRequestFullScreen) {
          element.mozRequestFullScreen();
        }
      } else {
      }
    },
    playWebSiteProgram(index) {
      let that = this;
      const webArr = this.programList[this.curMainProgram].programs;
      that.curWebUrl = webArr[index % webArr.length].media;
      this.timerWeb = setInterval(() => {
        index = index + 1;
        that.curWebUrl = webArr[index % webArr.length].media;
      }, Number(webArr[index % webArr.length].duration));
    },

    playVideoProgram(sourceIndex, loop) {
      this.$nextTick(() => {
        let index = null;
        if (sourceIndex == null) {
          index = 0;
        } else {
          index = sourceIndex;
        }

        let that = this;
        const videoElement = document.getElementById("play_box");
        console.log(videoElement);
        this.endedController = () => {
          if (loop == false) {
            index = index + 1;
          }
          that.playNextVideo(index);
        };
        videoElement.addEventListener("ended", this.endedController);
        this.playNextVideo(index);
      });
    },
    playNextVideo(index) {
      this.curSonIndex = index;
      console.log(this.curSonIndex);
      const videoArr = this.programList[this.curMainProgram].programs;
      const videoElement = document.getElementById("play_box");

      // 1. 暂停并清空当前视频
      videoElement.pause();
      videoElement.src = "";
      videoElement.load(); // 强制释放资源[1,6](@ref)

      let url = this.resourceRoot + videoArr[index % videoArr.length].media;
      // 方法1：直接设置src
      videoElement.src = url;
      videoElement.loop = false;

      videoElement
        .play()
        .then(() => console.log("播放成功"))
        .catch((error) => {
          console.error("自动播放被阻止，需要用户交互:", error);
          // 可以显示一个播放按钮，让用户手动触发
        });
    },
    playVideo(url) {
      const videoElement = document.getElementById("play_box");

      // 1. 暂停并清空当前视频
      videoElement.pause();
      videoElement.src = "";
      videoElement.load(); // 强制释放资源[1,6](@ref)

      // 方法1：直接设置src
      videoElement.src = url;
      videoElement
        .play()
        .then(() => console.log("播放成功"))
        .catch((error) => {
          console.error("自动播放被阻止，需要用户交互:", error);
          // 可以显示一个播放按钮，让用户手动触发
        });
      this.endedController = () => {
        // 1. 暂停并清空当前视频
        videoElement.pause();
        videoElement.src = "";
        videoElement.load(); // 强制释放资源[1,6](@ref)
        videoElement.src = url;
        videoElement
          .play()
          .then(() => console.log("播放成功"))
          .catch((error) => {
            console.error("自动播放被阻止，需要用户交互:", error);
            // 可以显示一个播放按钮，让用户手动触发
          });
      };
      videoElement.addEventListener("ended", this.endedController);
    },
    playStream(streamUrl) {
      this.isPlay = true;
      let videoElement = document.getElementById("play_box");
      if (flvjs.isSupported()) {
        this.flvPlayer = flvjs.createPlayer(
          {
            type: "flv",
            isLive: true,
            hasAudio: true,
            url: streamUrl,
          },
          {
            enableWorker: false, //不启用分离线程
            enableStashBuffer: false, //关闭IO隐藏缓冲区
            reuseRedirectedURL: true, //重用301/302重定向url，用于随后的请求，如查找、重新连接等。
            autoCleanupSourceBuffer: true, //自动清除缓存
          }
        );

        if (this.flvPlayer != null) {
          this.flvPlayer.attachMediaElement(videoElement);
          if (streamUrl !== "" && streamUrl !== null) {
            this.flvPlayer.load();
            this.flvPlayer.play();
            this.socket.send(
              JSON.stringify({
                isPlay: this.isPlay,
                suffix: this.curSuffix,
                pl_id: this.curPid,
                file_id: this.curFid,
                playMode: this.playMode,
                user_name: localStorage.getItem("user_name"),
              })
            );
          }
        }
      }

      this.speedAdjustInterval = setInterval(function () {
        if (videoElement.buffered.length > 0) {
          const end = videoElement.buffered.end(0); // 视频结尾时间
          const current = videoElement.currentTime; //  视频当前时间
          const diff = end - current; // 相差时间
          const diffCritical = 4; // 这里设定了超过4秒以上就进行跳转
          const diffSpeedUp = 1; // 这里设置了超过1秒以上则进行视频加速播放
          const maxPlaybackRate = 4; // 自定义设置允许的最大播放速度
          let playbackRate = 1.0; // 播放速度
          if (diff > diffCritical) {
            videoElement.currentTime = end - 1.5;
            playbackRate = Math.max(1, Math.min(diffCritical, 16));
          } else if (diff > diffSpeedUp) {
            playbackRate = Math.max(1, Math.min(diff, maxPlaybackRate, 16));
          }
          videoElement.playbackRate = playbackRate;
          if (videoElement.paused) {
            videoElement.play();
          }
        }
      }, 3000);
    },
    async onPlayer() {
      this.onStop();
      this.curProgramType = this.selectedProgramType;
      this.curMainProgram = this.selectedMainProgram;
      this.curSonProgram = this.selectedSonProgram;
      this.programInfo.programName =
        this.programList[this.curMainProgram].programName;
      this.programInfo.programType = "点播";
      this.programInfo.resourceNum =
        this.programList[this.curMainProgram].programs.length;
      this.programInfo.programDate = "/";
      this.programInfo.duration =
        this.programList[this.curMainProgram].pgDuration;
      this.programInfo.playTime = "/";
      if (
        this.playMode == null ||
        this.playMode != this.curPlayMode ||
        this.curPlayMode == 0
      ) {
        this.isPlay = false;
      }
      this.playMode = this.curPlayMode;
      if (this.selectedProgramType == "视频") {
        this.isPlay = true;
        if (this.playMode == 1) {
          this.playVideoProgram(this.curSonProgram, true);
        } else if (this.playMode == 0) {
          this.playVideoProgram(null, false);
        }
      } else if (this.selectedProgramType == "图片") {
        this.isPlay = true;
        console.log("进行图片播放");
      } else if (this.selectedProgramType == "ppt") {
        if (this.playMode == 0) {
          return;
        }
        this.$nextTick(() => {
          console.log("播放ppt");
          const media =
            this.programList[this.curMainProgram].programs[this.curSonProgram]
              .media;
          this.pptUrl = this.resourceRoot + media;
          this.pptKey =
            this.programList[this.curMainProgram].prefix + this.curSonProgram;
          // this.pptUrl =
          //   "https://center-control-1320487003.cos.ap-guangzhou.myqcloud.com/loop.pptx";
          // this.pptKey = "7885423210";
          this.isPlay = true;
        });
      } else if (this.selectedProgramType == "网页") {
        this.isPlay = true;
        if (this.playMode == 1) {
          const url =
            this.programList[this.curMainProgram].programs[this.curSonProgram]
              .media;
          this.curWebUrl = url;
        } else if (this.playMode == 0) {
          this.playWebSiteProgram(0);
        }
      } else if (this.selectedProgramType == "文本") {
        if (this.playMode == 1) {
          this.playText(this.curSonIndex, this.playMode == 1);
        } else {
          this.playText(0, this.playMode == 1);
        }
      }
      console.log(this.isPlay, this.curProgramType, this.playMode);
      this.startTimer();
    },
    playText(sonIndex, loop) {
      this.curSonIndex = sonIndex;
      sonIndex =
        sonIndex % this.programList[this.curMainProgram].programs.length;
      this.$nextTick(() => {
        this.isPlay = true;
        this.again = true;
        this.curFontSize =
          this.programList[this.curMainProgram].programs[sonIndex].fontSize;
        this.textContent =
          this.programList[this.curMainProgram].programs[sonIndex].media;
        this.curFontColor =
          this.programList[this.curMainProgram].programs[sonIndex].color;
        this.rowNum = Math.floor(this.contentHeight / this.curFontSize);
        this.$nextTick(() => {
          this.duration1 =
            Number(
              this.programList[this.curMainProgram].programs[sonIndex].duration
            ) / 1000;
          this.measureCharWidth();
          console.log("文本长度：" + this.charWidth);
          this.culculateDurations();
          console.log(this.duration2);
          const elements = document.querySelectorAll(".marquee-content");
          console.log(elements);
          this.rowArr = elements;
          for (let index = 0; index < elements.length; index++) {
            const element = elements[index];
            element.textShowIndex = index;
          }
          const lastElement = elements[elements.length - 1];
          this.playAnimation(lastElement, loop);
        });
      });
    },
    playAnimation(element, loop) {
      const animationMonitor = () => {
        if (element.style.animation.includes("marquee1")) {
          if (element.textShowIndex > 0) {
            const nextElement = this.rowArr[element.textShowIndex - 1];
            this.playAnimation(nextElement, loop);
          }
          element.style.animation =
            "marquee2 " + this.duration2 + "s linear forwards";
        } else {
          element.removeEventListener("animationend", animationMonitor);
          if (element.textShowIndex == 0) {
            console.log(123456);
            if (loop) {
              const nextElement = this.rowArr[this.rowArr.length - 1];
              this.playAnimation(nextElement, loop);
            } else {
              this.onStop();
              this.playText(this.curSonIndex + 1, loop);
            }
          }
        }
      };

      element.style.animation =
        "marquee1 " + this.duration1 + "s linear forwards";
      element.addEventListener("animationend", animationMonitor);
    },
    measureCharWidth() {
      const testEl = document.createElement("span");
      testEl.style.fontSize = this.curFontSize + "px";
      testEl.style.visibility = "hidden";
      testEl.style.position = "absolute";
      testEl.style.whiteSpace = "nowrap";
      testEl.style.height = this.curFontSize + "px";
      testEl.style.background = "white";
      testEl.style.fontFamily = "system-ui";
      testEl.style.lineHeight = this.curFontSize + "px";
      testEl.textContent = this.textContent;
      document.body.appendChild(testEl);
      this.charWidth = testEl.offsetWidth;
      document.body.removeChild(testEl);
    },
    culculateDurations() {
      this.duration2 = (this.charWidth / this.windowWidth) * this.duration1;
    },
    startTimer() {
      if (!this.isRunning) {
        this.isRunning = true;
        this.timer = setInterval(() => {
          this.seconds++;
        }, 1000);
      }
    },
    stopTimer() {
      if (this.isRunning) {
        clearInterval(this.timer);
        clearTimeout(this.timerWeb);
        this.isRunning = false;
      }
    },

    onPause() {
      if (this.curProgramType == "视频") {
        const videoElement = document.getElementById("play_box");
        videoElement.pause();
        this.isPause = true;
      }
    },
    onStop() {
      this.stopStream();
      this.stopPPT();
      this.stopTimer();
      this.isPlay = false;
      this.again = false;
    },
    stopPPT() {
      if (this.docEditor == null) {
        return;
      }
      this.docEditor.destroyEditor();
      this.docEditor = null;
      const placeholder = document.getElementById("placeholder");
      if (placeholder) {
        placeholder.innerHTML = ""; // 清空内容
        placeholder.remove(); // 移除节点
      }
    },
    onReplay() {},
    async stopStream() {
      const videoElement = document.getElementById("play_box");
      if (videoElement == null) {
        return;
      }
      // 1. 暂停播放
      videoElement.pause();

      // 2. 重置播放位置
      videoElement.currentTime = 0;

      // 3. 移除视频源（重要！这会释放解码器和网络资源）
      videoElement.src = "";
      videoElement.removeAttribute("src");
      // 5. 触发load()方法应用更改
      videoElement.load();
      videoElement.onplay = null;
      videoElement.onpause = null;
      videoElement.removeEventListener("ended", this.endedController);
    },
    selectMainProgram(index) {
      this.curPlayMode = 0;
      this.selectedMainProgram = index;
      this.selectedSonProgram = null;
      this.curSuffix = this.programList[index].suffix;
      this.curPid = this.programList[index].id;
      this.selectedProgramType = this.programList[index].programType;
    },
    selectSonProgram(index, item) {
      this.curPlayMode = 1;
      this.curFid = item.id;
      this.selectedSonProgram = index;
    },
    async getProgramList() {
      this.programList = null;
      let res = await request({
        url: "/program/api/getProgramList",
        method: "POST",
        data: {
          command: 10,
          user_name: localStorage.getItem("user_name"),
          data: [
            {
              id: -1,
              pl_id: -1,
            },
          ],
        },
      });
      if (res.data.status == 200) {
        this.programList = res.data.data.data;
      }
    },
    loadONLYOFFICEApi() {
      const script = document.createElement("script");
      script.type = "text/javascript";
      script.src =
        "http://" + this.hostname + ":9090/web-apps/apps/api/documents/api.js";

      // 可选：添加加载成功/失败的回调
      script.onload = () => console.log("ONLYOFFICE API脚本加载成功");
      script.onerror = () => console.error("脚本加载失败");

      document.head.appendChild(script);
    },
    async connectWs() {
      let res = await request({
        url: "/user/api/getRandomId",
        method: "GET",
      });
      if (res.data.status == 200) {
        this.tokenId = "preview" + res.data.data;
        console.log("开始连接ws");
        this.initWs(this.tokenId);
      }
    },
    initWs(wsId) {
      if (this.socket) {
        this.socket.close();
        this.socket = null;
      }
      console.log("开始连接ws");
      if (typeof WebSocket === "undefined") {
        alert("您的浏览器不支持socket");
      } else {
        let wsUrl = window.location.origin.replace("http://", "");
        // 实例化socket 111是固定的用户id,正式环境直接获取当前登录用户id
        this.socket = new WebSocket(
          "ws:" + "192.168.0.16:8093" + "/wsServer/" + wsId
        );
        // this.socket = new WebSocket("ws:" + wsUrl + "//wsServer/" + wsId);
        this.global.setWs(this.socket);
        let that = this;
        // 监听socket连接
        this.socket.onopen = () => {
          console.log("socket连接成功");
        };
        // 监听socket错误信息
        this.socket.onerror = () => {
          console.error("连接错误");
          const connectTimeout = setTimeout(() => {
            this.initWs(wsId);
            clearTimeout(connectTimeout);
          }, this.retryTimeout);
        };
        //监听socket消息
        this.socket.onmessage = (msg) => {
          let jsonObject = JSON.parse(msg.data);
          console.log(jsonObject);
        };
        // 监听socket关闭信息
        this.socket.onclose = (e) => {
          console.log("socket已经关闭");
        };
      }
    },
    destoryFlv() {
      if (this.flvPlayer == null) {
        return;
      }
      this.flvPlayer.pause();
      this.flvPlayer.unload();
      this.flvPlayer.detachMediaElement();
      this.flvPlayer.destroy();
      this.flvPlayer = null;
      if (this.speedAdjustInterval) {
        clearInterval(this.speedAdjustInterval);
        this.speedAdjustInterval = null;
      }
    },
  },
  beforeDestroy() {
    // 组件销毁前关闭连接
    if (this.socket) {
      this.socket.close();
      this.socket = null;
    }
    if (this.flvPlayer == null) {
      return;
    }

    this.onStop();
  },
  mounted() {
    const resizeObserver = new ResizeObserver((entries) => {
      requestAnimationFrame(() => {
        for (const entry of entries) {
          this.contentHeight = entry.contentRect.height;
          this.windowWidth = entry.contentRect.width;
          if (this.isPlay && this.curProgramType == "文本") {
            this.again = false;
            this.rowNum = Math.floor(
              entry.contentRect.height / this.curFontSize
            );
            this.playText(this.curSonIndex, this.playMode == 1);
          }
        }
      });
    });
    resizeObserver.observe(document.getElementById("realContent"));
    const fullUrl = window.location.href;
    const ipRegex = /\b(?:\d{1,3}\.){3}\d{1,3}\b/;
    const ipInUrl = fullUrl.match(ipRegex)?.[0];
    this.resourceRoot = "http://" + ipInUrl + ":8093/assets/";
    const url = new URL(this.resourceRoot);
    this.hostname = url.hostname; // 提取主机名（可能是IP或域名）
    // this.loadONLYOFFICEApi();
    this.connectWs();
    this.getProgramList();
  },
};
</script>

<style>
.icon-luxiang2 {
  display: none !important;
}
.marquee-row {
  position: relative;
  overflow: hidden;
  white-space: nowrap;
}

.marquee-content {
  transform: translateZ(0);
  display: inline-block;
  padding-left: 100% !important;
  will-change: transform;
  font-family: system-ui;
}

@keyframes marquee1 {
  0% {
    transform: translateX(0);
  }
  100% {
    transform: translateX(calc(-100% + var(--char-width)));
  }
}
@keyframes marquee2 {
  0% {
    transform: translateX(calc(-100% + var(--char-width)));
  }
  100% {
    transform: translateX(calc(-100%));
  }
}
</style>